package main

import (
	"bufio"
	"fmt"
	"os"
)

/*
1、
func OpenFile(name string, flag int, perm FileMode) (file *File, err error)
OpenFile是一个更一般性的文件打开函数，大多数调用者都应用Open或Create代替本函数。
它会使用指定的选项（如O_RDONLY等）、指定的模式（如0666等）打开指定名称的文件。
如果操作成功，返回的文件对象可用于I/O。
如果出错，错误底层类型是*PathError。
第二个参数：文件打开模式(可以组合)
const (
    O_RDONLY int = syscall.O_RDONLY // 只读模式打开文件
    O_WRONLY int = syscall.O_WRONLY // 只写模式打开文件
    O_RDWR   int = syscall.O_RDWR   // 读写模式打开文件
    O_APPEND int = syscall.O_APPEND // 写操作时将数据附加到文件尾部
    O_CREATE int = syscall.O_CREAT  // 如果不存在将创建一个新文件
    O_EXCL   int = syscall.O_EXCL   // 和O_CREATE配合使用，文件必须不存在
    O_SYNC   int = syscall.O_SYNC   // 打开文件用于同步I/O
    O_TRUNC  int = syscall.O_TRUNC  // 如果可能，打开时清空文件
)
第三个参数：权限控制(linux)
2、案例
(1)创建一个新文件，写入内容 5句"hello,Gardon"
(2)打开一个存在的文件中，将原来的内容覆盖成新的内容10句"你好，猪猪"
(3)打开一个存在的文件，在原来的内容追加内容"ABC!ENGLISH!"
(4)打开一个存在的文件，将原来的内容读出显示在终端，并且追加5句"hello,北京"
使用os.OpenFile(),bufio.NewWriter()，*Writer的方法WriterString完成上面的任务
*/
func main() {
	//案例(1)
	filePath := "src/go_code/chapter14/5写文件/test.txt"
	/*
		这里将os.O_CREATE改成os.O_TRUNC，然后将写的内容改了就是案例(2)
		这里将os.O_CREATE改成os.O_APPEND，就是案例(3)
		先将文件中的内容读出来，再使用(3)就是案例(4)
	*/
	file, err := os.OpenFile(filePath, os.O_WRONLY|os.O_CREATE, 0666)
	if err != nil {
		fmt.Printf("open file err=%v\n", err)
		return
	}
	//及时关闭file句柄
	defer file.Close()
	str := "hello,Gardon\r\n" // \r\n表示换行
	// str := "你好，猪猪\r\n"
	//写入时，使用带缓存的*Writer
	writer := bufio.NewWriter(file)
	for i := 0; i < 5; i++ {
		writer.WriteString(str)
	}
	//因为writer是带缓存的，因此在调用WriterString方法时，
	//其实内容是先写入到缓存的，所以需要调用Flush方法，将缓冲的数据真正写到文件中，否则文件中会没有数据
	writer.Flush()
}
